package com.apanal.qlife.common.filter;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;

import com.alibaba.fastjson.JSON;
import com.apanal.qlife.common.constants.Constants;

/**
 * 强制退出用户过滤器
 * 
 * 
 * @author shuliangxing
 * 
 * @date 2015-10-19下午2:53:10
 */
public class ForceLogoutFilter extends AccessControlFilter {

	@Override
	protected boolean isAccessAllowed(ServletRequest request,
			ServletResponse response, Object mappedValue) throws Exception {
		Session session = getSubject(request, response).getSession(false);
		if (session == null) {
			return true;
		}
		return session.getAttribute(Constants.SESSION_FORCE_LOGOUT_KEY) == null
				&& session.getAttribute(Constants.SESSION_REPEAT_LOGIN_KEY) == null
				&& session.getAttribute(Constants.SESSION_USER_LOCKED_KEY) == null
				&& session.getAttribute(Constants.SESSION_ORG_DISABLE_KEY) == null;
	}

	@Override
	protected boolean onAccessDenied(ServletRequest request,
			ServletResponse response) throws Exception {
		HttpServletRequest req = WebUtils.toHttp(request);
		HttpServletResponse rsp = WebUtils.toHttp(response);
		Subject subject = getSubject(request, response);

		if (subject == null) {
			return false;
		}
		Session session = subject.getSession(false);
		if (session == null) {
			return false;
		}
		String flg = "";
		String msg = Constants.MSG_DEFAULT_FORCE_LOGOUT;
		// 重复登录
		if (session.getAttribute(Constants.SESSION_REPEAT_LOGIN_KEY) != null) {
			flg = Constants.URL_REPEAT_LOGIN + "=1";
			msg = Constants.MSG_REPEAT_LOGIN;
		}
		// 管理员强制退出
		else if (session.getAttribute(Constants.SESSION_FORCE_LOGOUT_KEY) != null) {
			flg = Constants.URL_FORCE_LOGOUT + "=1";
			msg = Constants.MSG_FORCE_LOGOUT;
		}
		// 账号被锁
		else if (session.getAttribute(Constants.SESSION_USER_LOCKED_KEY) != null) {
			flg = Constants.URL_USER_LOCKED + "=1";
			msg = Constants.MSG_USER_LOCKED;
		}
		// 账号直属机构停用
		else if (session.getAttribute(Constants.SESSION_ORG_DISABLE_KEY) != null) {
			flg = Constants.URL_ORG_DISABLE + "=1";
			msg = Constants.MSG_ORG_DISABLE;
		}

		// 预留代码
		// String backUrl = req.getRequestURI();
		// backUrl = backUrl.replace(req.getContextPath(), "");

		try {
			// 强制退出,注意session已清空
			subject.logout();// 强制退出
		} catch (Exception e) {/* ignore exception */
		}

		String loginUrl = getLoginUrl()
				+ (getLoginUrl().contains("?") ? "&" : "?") + flg;

		// 预留代码,目前登录统一采用最顶层页面登录,iframe子页面登录如果登录账号不一致会导致父页面登录人信息不一致
		// 参考com.apanal.qlife.common.jcaptcha.MyFormAuthenticationFilter
		// loginUrl += "&backUrl="+ backUrl;

		// 如果是异步请求(Ajax),设置踢出状态并返回错误提示信息
		if (com.apanal.qlife.common.util.WebUtils.isAjaxRequest(req)) {
			// 设置自定义用户被踢下线状态码
			rsp.setStatus(Constants.HTTP_CODE_FORCE_LOGOUT);
			Map<String, String> jsonMap = new HashMap<String, String>();
			jsonMap.put("msg", msg);
			jsonMap.put("url", loginUrl);
			// ajax请求失败时隐式显示错误信息
			com.apanal.qlife.common.util.WebUtils.sendData(
					JSON.toJSONString(jsonMap), rsp);
		} else {
			WebUtils.issueRedirect(request, response, loginUrl);
		}
		return false;
	}

}
